package pers.zb.cloud.service.upms.service.impl;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.zb.cloud.service.upms.dao.PermissionMapper;
import pers.zb.cloud.service.upms.entity.SysMenu;
import pers.zb.cloud.service.upms.entity.SysPermission;
import pers.zb.cloud.service.upms.enums.MenuShape;
import pers.zb.cloud.service.upms.enums.MenuStatus;
import pers.zb.cloud.service.upms.enums.MenuType;
import pers.zb.cloud.service.upms.enums.PermissionStatus;
import pers.zb.cloud.service.upms.service.PermissionService;
import pers.zb.cloud.service.upms.util.PermissionTreeUtil;
import pers.zb.cloud.service.upms.util.sequence.IdWorker;
import pers.zb.cloud.service.upms.vo.PermissionVo;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("permissionServiceImpl")
public class PermissionServiceImpl extends BaseServiceImpl<SysPermission> implements PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public List<SysPermission> getPermissionList(List<Long> permissionIdList) {
        Example example = new Example(SysPermission.class);
        example.createCriteria().andIn("id",permissionIdList);
        List<SysPermission> permissions = permissionMapper.selectByExample(example);
        return permissions;
    }

    @Override
    public SysPermission getPermissionById(Long id) {
        return permissionMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<PermissionVo> getPermissionListByPid(Long pid, String clientId) {
        Example example = new Example(SysPermission.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("pid",pid).andNotEqualTo("status", MenuStatus.DELETE);

        if(!StringUtils.isEmpty(clientId) && !clientId.equals("-1")){ // -1 表示的是最顶层的父节点，也就是我们自定义的分组名称，该节点不是一个应用 。 具体业务代码请看 getClientListTree 方法。
            criteria.andEqualTo("clientId",clientId);
        }
        List<SysPermission> sysPermissionList = permissionMapper.selectByExample(example);

        List<PermissionVo> permissionVoList = new ArrayList<>();
        if(sysPermissionList == null || sysPermissionList.size() <= 0){
            return permissionVoList;
        }

        for (SysPermission sysPermission : sysPermissionList) {
            PermissionVo permissionVo = new PermissionVo();
            permissionVo.setId(sysPermission.getId());
            permissionVo.setPid(sysPermission.getPid());
            permissionVo.setCode(sysPermission.getCode());
            //permissionVo.setComment(sysPermission.getDescription());
            permissionVo.setName(sysPermission.getName());
            permissionVo.setStatus(sysPermission.getStatus());
            permissionVo.setType(sysPermission.getType());
            permissionVo.setIcon(sysPermission.getIcon());
            permissionVo.setState(sysPermission.getShape().getValue());
            permissionVo.setClientId(sysPermission.getClientId());
            permissionVo.setCreateTime(sysPermission.getCreateTime());
            permissionVo.setUpdateTime(sysPermission.getUpdateTime());
            permissionVo.setDescription(sysPermission.getDescription());
            permissionVo.setIconCls(sysPermission.getIcon());
            permissionVoList.add(permissionVo);
        }

        //对于拥有子菜单的菜单，递归获取所有层级的子菜单数据
        List<PermissionVo> permissionTreeList =  PermissionTreeUtil.getPermissionTreeList(permissionVoList,pid);
        return permissionTreeList;
    }

    @Override
    public boolean haveChildrenMenu(Long id) {
        Example example = new Example(SysPermission.class);
        example.createCriteria().andEqualTo("pid",id);
        List<SysPermission> sysPermissionList = permissionMapper.selectByExample(example);
        if(sysPermissionList != null && sysPermissionList.size() > 0){
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public void addPermission(SysPermission sysPermission) {
        //如果选中的上级菜单的子菜单数量为 0 的话，需要更新上级菜单的state为closed
        Example example = new Example(SysPermission.class);
        example.createCriteria().andEqualTo("pid",sysPermission.getPid()).andNotEqualTo("status",MenuStatus.DELETE);
        List<SysPermission> sysPermissionList = permissionMapper.selectByExample(example);
        if(sysPermissionList == null || sysPermissionList.size() <= 0){
            SysPermission sysPermissionParent = getPermissionById(sysPermission.getPid());
            sysPermissionParent.setShape(MenuShape.CLOSED);
            sysPermissionParent.setType(MenuType.DIRECTORY);
            sysPermissionParent.setUpdateTime(new Date());
            permissionMapper.updateByPrimaryKeySelective(sysPermissionParent);
        }

        sysPermission.setId(IdWorker.id.nextId());
        sysPermission.setCreateTime(new Date());
        sysPermission.setShape(MenuShape.OPEN);
        sysPermission.setType(MenuType.NODE);
        sysPermission.setUpdateTime(new Date());
        permissionMapper.insert(sysPermission);
    }

    @Override
    @Transactional
    public void updatePermission(SysPermission sysPermission) throws Exception {
        if(sysPermission == null){
            throw new Exception("对象为null");
        }
        //如果选中的菜单下面没有子菜单的话，需要设置state的值为closed，表明是一个父节点（由于前端框架的限制，所以是closed值，固定值）
        boolean haveChildrenMenu = haveChildrenMenu(sysPermission.getPid());
        if(!haveChildrenMenu){
            SysPermission sysPermissionParent = getPermissionById(sysPermission.getPid());
            sysPermissionParent.setShape(MenuShape.CLOSED);
            sysPermissionParent.setType(MenuType.DIRECTORY);
            sysPermissionParent.setUpdateTime(new Date());
            permissionMapper.updateByPrimaryKeySelective(sysPermissionParent);
        }

        SysPermission currentPermission = permissionMapper.selectByPrimaryKey(sysPermission.getId());//当前更新的权限节点

        Example example = new Example(SysPermission.class);
        example.createCriteria().andEqualTo("pid",currentPermission.getPid());
        List<SysPermission> sysPermissionList = permissionMapper.selectByExample(example);
        //当前更新的权限节点的父节点只有当前更新的权限的这一个子权限节点
        if(sysPermissionList != null && sysPermissionList.size() <= 1){
            SysPermission sysPermissionParent = getPermissionById(currentPermission.getPid());
            sysPermissionParent.setShape(MenuShape.OPEN);
            sysPermissionParent.setType(MenuType.NODE);
            sysPermissionParent.setUpdateTime(new Date());
            permissionMapper.updateByPrimaryKeySelective(sysPermissionParent);
        }

        sysPermission.setUpdateTime(new Date());
        permissionMapper.updateByPrimaryKeySelective(sysPermission);
    }

    @Override
    public List<PermissionVo> getPermissionListByNotItself(Long id, String clientId) {
        Example example = new Example(SysPermission.class);
        example.createCriteria()
                .andNotEqualTo("id",id) //除了自身外
                .andNotEqualTo("status", PermissionStatus.DISABLE)
                .andEqualTo("clientId",clientId);
        List<SysPermission> sysPermissionList = permissionMapper.selectByExample(example);

        List<PermissionVo> menuVoList = new ArrayList<>();
        if(sysPermissionList == null || sysPermissionList.size() <= 0){
            return menuVoList;
        }

        for (SysPermission sysPermission : sysPermissionList) {
            PermissionVo permissionVo = new PermissionVo();
            permissionVo.setId(sysPermission.getId());
            permissionVo.setPid(sysPermission.getPid());
            permissionVo.setCode(sysPermission.getCode());
            permissionVo.setComment(sysPermission.getDescription());
            permissionVo.setName(sysPermission.getName());
            permissionVo.setStatus(sysPermission.getStatus());
            permissionVo.setType(sysPermission.getType());
            permissionVo.setIcon(sysPermission.getIcon());
            permissionVo.setState(sysPermission.getShape().getValue());
            menuVoList.add(permissionVo);
        }

        //对于拥有子权限的菜单，递归获取所有层级的子权限数据
        List<PermissionVo> permissionTreeList =  PermissionTreeUtil.getPermissionTreeList(menuVoList);
        return permissionTreeList;
    }

    @Override
    @Transactional
    public void deletePermission(Long[] permissionIdArrs) throws Exception {
        for (Long id : permissionIdArrs) {
            SysPermission sysPermission = getPermissionById(id);
            if(sysPermission == null){
                throw new Exception("权限不存在");
            }
            sysPermission.setStatus(PermissionStatus.DELETE);
            sysPermission.setUpdateTime(new Date());
            permissionMapper.updateByPrimaryKeySelective(sysPermission);

            if(sysPermission.getPid().longValue() != -1L){
                //如果当前菜单的上级菜单的子菜单数量为 1 的话（说明子菜单是当前的菜单），删除当前菜单后，需要更新上级菜单的state为open，说明是没有子菜单的（由于前端框架的限制，所以是open值，固定值）
                Example example = new Example(SysMenu.class);
                example.createCriteria().andEqualTo("pid",sysPermission.getPid()).andNotEqualTo("status",MenuStatus.DELETE);
                List<SysPermission> sysPermissionList = permissionMapper.selectByExample(example);
                if(sysPermissionList != null && sysPermissionList.size() <= 1){
                    SysPermission sysPermissionParent = getPermissionById(sysPermission.getPid());
                    sysPermissionParent.setShape(MenuShape.OPEN);
                    sysPermissionParent.setType(MenuType.NODE);
                    sysPermissionParent.setUpdateTime(new Date());
                    permissionMapper.updateByPrimaryKeySelective(sysPermissionParent);
                }
            }
        }
    }
}
